﻿using Opc.Ua;
using Opc.Ua.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using SiemensOPC;
using System.Runtime.CompilerServices;
using VswService_V7.Config;

namespace VswService_V7.OPC.DB
{
    public class HeartBeatCheckAddressDbData : SubscriptionDbDataBase, INotifyPropertyChanged
    {
        #region property notify
        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName, object propertyValue)
        {
            PropertyChanged?.Invoke(propertyValue, new PropertyChangedEventArgs(propertyName));
        }

        protected void UpdatePorperty<T>(ref T item, T newValue, [CallerMemberName] string propertyName = "NULL")
        {
            if (!EqualityComparer<T>.Default.Equals(item, newValue))
            {
                item = newValue;
                OnPropertyChanged(propertyName, newValue);
            }
        }
        #endregion

        public HeartBeatCheckAddressDbData(SimaticOPCClient opc, NodeConfig nodes) : base(opc, nodes)
        {
			HeartBeatEntryConnectionStatus = false;
			HeartBeatMainConnectionStatus = false;
			HeartBeatSzConnectionStatus = false;
			HeartBeatFn1ConnectionStatus = false;
            HeartBeatFn3ConnectionStatus = false;
        }

        #region Properity

        //public bool Heartbeat { get; set; }
        private bool _heartBeatEntryConnectionStatus;
		private bool _heartBeatMainConnectionStatus;
		private bool _heartBeatSzConnectionStatus;
		private bool _heartBeatFn1ConnectionStatus;
        private bool _heartBeatFn3ConnectionStatus;
        /// <summary>
        /// 通过心跳信号，表示与通讯对象的连接状态
        /// </summary>
        public bool HeartBeatEntryConnectionStatus
		{
            get
            {
                return _heartBeatEntryConnectionStatus;
            }
            private set
            {
                UpdatePorperty(ref _heartBeatEntryConnectionStatus, value);
            }
        }
		public bool HeartBeatMainConnectionStatus
		{
			get
			{
				return _heartBeatMainConnectionStatus;
			}
			private set
			{
				UpdatePorperty(ref _heartBeatMainConnectionStatus, value);
			}
		}
		public bool HeartBeatSzConnectionStatus
		{
			get
			{
				return _heartBeatSzConnectionStatus;
			}
			private set
			{
				UpdatePorperty(ref _heartBeatSzConnectionStatus, value);
			}
		}
		public bool HeartBeatFn1ConnectionStatus
		{
			get
			{
				return _heartBeatFn1ConnectionStatus;
			}
			private set
			{
				UpdatePorperty(ref _heartBeatFn1ConnectionStatus, value);
			}
		}
        public bool HeartBeatFn3ConnectionStatus
        {
            get
            {
                return _heartBeatFn3ConnectionStatus;
            }
            private set
            {
                UpdatePorperty(ref _heartBeatFn3ConnectionStatus, value);
            }
        }
        #endregion

        public override void CreateSubscription()
        {
            try
            {				
				opcServer.QuickAddMonitorItem(opcNodes.HeartBeatCheckAddress.GrpoupName,
					opcNodes.HeartBeatCheckAddress.PublishTime, opcNodes.HeartBeatCheckAddress.SampleTime,
					opcNodes.HeartBeatCheckAddress.GetNodeAddress(), opcNodes.HeartBeatCheckAddress.GetNodeDisplayName(),
					SubscriptionHandler);
			}
            catch (Exception e)
            {
                throw e;
            }
        }		
        private void SubscriptionHandler(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
			if (notification == null || notification.Value.Value == null)
				return;
			if (monitoredItem.DisplayName == "HeartBeatEntry")
			{
				bool result = false;
				if (bool.TryParse(notification.Value.Value.ToString(), out result))
				{
					try
					{
						opcServer.WriteValue((!result).ToString(), opcNodes.HeartBeatCheckAddress.HeartBeatEntry);
						HeartBeatEntryConnectionStatus = true;
					}
					catch
					{
						HeartBeatEntryConnectionStatus = false;
					}
				}
			}
			else if (monitoredItem.DisplayName == "HeartBeatMain")
			{
				bool result = false;
				if (bool.TryParse(notification.Value.Value.ToString(), out result))
				{
					try
					{
						opcServer.WriteValue((!result).ToString(), opcNodes.HeartBeatCheckAddress.HeartBeatMain);
						HeartBeatMainConnectionStatus = true;
					}
					catch
					{
						HeartBeatMainConnectionStatus = false;
					}
				}
			}
			else if (monitoredItem.DisplayName == "HeartBeatSz")
			{
				bool result = false;
				if (bool.TryParse(notification.Value.Value.ToString(), out result))
				{
					try
					{
						opcServer.WriteValue((!result).ToString(), opcNodes.HeartBeatCheckAddress.HeartBeatSz);
						HeartBeatSzConnectionStatus = true;
					}
					catch
					{
						HeartBeatSzConnectionStatus = false;
					}
				}
			}
			else if (monitoredItem.DisplayName == "HeartBeatFn_1")
			{
				bool result = false;
				if (bool.TryParse(notification.Value.Value.ToString(), out result))
				{
					try
					{
						opcServer.WriteValue((!result).ToString(), opcNodes.HeartBeatCheckAddress.HeartBeatFn_1);
						HeartBeatFn1ConnectionStatus = true;
					}
					catch
					{
						HeartBeatFn1ConnectionStatus = false;
					}
				}
			}
			else if (monitoredItem.DisplayName == "HeartBeatFn_3")
			{				
				bool result = false;
				if (bool.TryParse(notification.Value.Value.ToString(), out result))
				{
					try
					{						
						opcServer.WriteValue((!result).ToString(), opcNodes.HeartBeatCheckAddress.HeartBeatFn_3);
						HeartBeatFn3ConnectionStatus = true;
					}
					catch
					{
						HeartBeatFn3ConnectionStatus = false;
					}
				}
			}
		}
    }
}
